require "uri"
require "pg"
require 'common_stuff'


class PEntriesController < ApplicationController
  include CommonStuff
  before_action :set_p_entry, only: [:show, :edit, :update, :destroy]

public 
  def labeltoStatus(label)
    puts "====labeltoStatus started"
    arr=label.split('#')
    puts "labeltostatus:",arr
    if(arr[0] != 'h')
      return "NOTHLABEL"
    else
      return arr[1]
    end
  end

  def GetStatusFromStoryLabel(story)
      labels=story.labels
      puts "labels:",labels.length
      status=-1
      labels.each do |label|
        r=labeltoStatus(label.name.to_s)
        puts "r:",r
        if(r!= "NOTHLABEL")
          status=r
          puts "status",status 
          return status
        end
      end
      puts "status",status 
      return status
  end

  def preprocess
    token = session[:ptracker_token].to_s
    date  = Date.today.to_formatted_s(:db).to_s
    entry = PEntry.where("token = ? AND date = ?",token,date)

    entry.each do |e|
      start_time = StateTrans.find_by_sql("Select commit_time from state_trans where story_id = '"+e.story_id.to_s+"'and current_state='unstarted' and new_state='started' limit 1")
      end_time = StateTrans.find_by_sql("Select commit_time from state_trans where story_id = '"+e.story_id.to_s+"'and current_state='started' and new_state='finished' limit 1")
      if(start_time.first==nil and end_time.first==nil)
        puts "in schedule"
      elsif(start_time.first!=nil and end_time.first==nil)
        puts "in process"
      elsif(start_time.first==nil and end_time.first!=nil)
        puts "something wrong"
      else
        puts "start_time",start_time.first.commit_time
        puts "end_time",end_time.first.commit_time
        connection = ActiveRecord::Base.connection
        interval=connection.execute("SELECT  '"+end_time.first.commit_time.to_s+"'::timestamp - '"+start_time.first.commit_time.to_s+"'::timestamp as intervaltime")
        puts "interval:",interval.first["intervaltime"]
        save_in_done(interval.first["intervaltime"],e,date)
      end
    end
  end

  def GetFormattedDateFieldFromPT(date)
     ar=date.to_s.split(" ")
     # puts "GetFormattedDateFieldFromPT:",ar[0].to_s
     return ar[0].to_s
  end

  def GetFormattedDateSlash(date)
    ar=date.to_s.split(" ")
    year=ar[3].to_s
    day=ar[2].to_s
    month=ar[1].to_s
    # puts month
    case month.to_s
    when "Jan"
      mon="01"
    when "Feb"
      mon="02"
    when "Mar"
      mon="03"
    when "Apr"
      mon="04"
    when "May"
      mon="05"
    when "Jun"
      mon="06"
    when "Jul"
      mon="07"
    when "Aug"
      mon="08"
    when "Sep"
      mon="09"
    when "Oct"
      mon="10"
    when "Nov"
      mon="11"
    when "Dec"
      mon="12"
    else
      mon=""
    end
    return mon+"/"+day+"/"+year
  end

  def GetFormattedDateHyphen(date)
    puts "=====",__method__,"====="
    puts "raw input date:",date
    ar=date.to_s.split(" ")
    year=ar[3].to_s
    day=ar[2].to_s
    month=ar[1].to_s
    # puts month
    case month.to_s
    when "Jan"
      mon="01"
    when "Feb"
      mon="02"
    when "Mar"
      mon="03"
    when "Apr"
      mon="04"
    when "May"
      mon="05"
    when "Jun"
      mon="06"
    when "Jul"
      mon="07"
    when "Aug"
      mon="08"
    when "Sep"
      mon="09"
    when "Oct"
      mon="10"
    when "Nov"
      mon="11"
    when "Dec"
      mon="12"
    else
      mon=""
    end

    return  ssdate=year.to_s+'-'+mon.to_s+'-'+day.to_s
  end



#grab the latest version of entries which have been updated since today
  def grab_entry
    puts "=====",__method__,"====="

    datefrompicker=params[:date]
    ddd=GetFormattedDateHyphen(datefrompicker)
    # puts "date:",datefrompicker
    # puts "ddd:",ddd
    date_after=ddd+"T00:00:00Z"
    date_before=ddd+"T23:59:59Z"
    puts "after:",date_after
    puts "before:",date_before
    date_ISO=Date.today.to_formatted_s(:db).to_s+"T00:00:00Z";  #yyyy-mm-ddT01:23:45Z
    date_simple=Date.today.to_formatted_s(:db).to_s             #yyyy-mm-dd
    # grab entry from ptracker
    token =session[:ptracker_token].to_s
    client = TrackerApi::Client.new(token: token) 
    projects=client.projects
    projects.each do |project|
      print "Project:",project.name,"\n"
      stories=project.stories(updated_after:date_after,updated_before:date_before)
      stories.each do |story|
        # save in our database
        @p_entry = PEntry.new()
        print "    Story:",story.name,"\n"
        trackerurl = "https://www.pivotaltracker.com/services/v5/projects/"+story.project_id.to_s+"/stories/"+story.id.to_s+"/activity"
        puts "trackerurl:",trackerurl
        c = Curl::Easy.new(trackerurl) do |curl| 
            curl.headers["X-TrackerToken"] = session[:ptracker_token].to_s
            curl.verbose = true
        end
        c.perform
        status=-1
        activities = JSON.parse(c.body_str)
        activities.each do |activity|
          if (activity["kind"]=="comment_create_activity" || activity["kind"]=="comment_update_activity")
            changes = activity["changes"]
            # puts changes
            changes.each do |change|
              if change["kind"]=="comment"
                @msg = change["new_values"]["text"]
                break
              end
            end
            puts "msg:",@msg
            msgarr =parse_message(@msg)
            if(msgarr==nil)
              puts "useless message"
              next
            else
              puts "message",msgarr
              status = msgarr[1]
              puts "status",status
              break
            end
          end
        end

      #search to see if there exists a  entry with the same storyid & date
        old_entry=PEntry.where({story_id:story.id.to_s , date:date_simple }).first_or_create do |p_entry|
          p_entry.story_id=story.id
          p_entry.token=token
          p_entry.project_id=story.project_id
          p_entry.project_name=project.name
          p_entry.story_name=story.name
          p_entry.story_type=story.story_type
          p_entry.story_description=story.description
          p_entry.current_state=story.current_state
          p_entry.date=ddd
          p_entry.status=status
          p_entry.pt_created_at=story.created_at
          p_entry.pt_updated_at=story.updated_at 
          p_entry.deadline=story.deadline
          p_entry.url=story.url
        end

      #there is a entry that can match our date and storyid
        if(old_entry != nil)
          PEntry.where({story_id:story.id.to_s , date:date_simple }).update_all(
                  :project_name          => project.name,                  
                  :story_name            => story.name,
                  :story_type        => story.story_type,
                  :story_description => story.description,
                  :current_state    => story.current_state,
                  :status           => status,
                  :pt_updated_at    => story.updated_at,
                  :deadline         => story.deadline
            )
        end
      end
    end

    respond_to do |format|
      format.html
      format.js    
      format.json  
    end
  end





#grab data from github by 
  def grab_state_trans_and_github
    puts "=====",__method__,"====="
    ptracker_token=session[:ptracker_token]
    date=Date.today.to_formatted_s(:db).to_s
    p_entry= PEntry.where("token=? and date=?",ptracker_token,date)
    p_entry.each do |pe|
      trackerurl = "https://www.pivotaltracker.com/services/v5/projects/"+pe.project_id.to_s+"/stories/"+pe.story_id.to_s+"/activity" 
      story_updateX=StoryUpdate.find_by(story_id:pe.story_id.to_s)
      if story_updateX!=nil
         trackerurl+= "?occurred_after="+story_updateX.ac_update_before.to_s
      end
      puts "trackerurl:",trackerurl
      c = Curl::Easy.new(trackerurl) do |curl| 
          curl.headers["X-TrackerToken"] = session[:ptracker_token].to_s
          curl.verbose = true
      end
      c.perform
      # puts c.body_str
      
      activities = JSON.parse(c.body_str)
      if story_updateX==nil or story_updateX.cm_update_before==nil or story_updateX.ac_update_before==nil
         ac_update_before="0"
         cm_update_before="0"
      else
         ac_update_before=story_updateX.ac_update_before
         cm_update_before=story_updateX.cm_update_before
      end

      # puts "acti:",activities

      puts "activities number:",activities.length
      activities.each do |activity|
        # puts activity["kind"]
        if ac_update_before<activity["occurred_at"]
          ac_update_before=activity["occurred_at"]
        end
    # ========state_trans stuff
        if activity["changes"] == nil
          next
        else
          activity["changes"].each do |change|
              story_state_trans = StateTrans.new()
              story_state_trans.story_id=pe.story_id.to_s
              if change["original_values"] == nil
                next
              else
                if change["original_values"]["current_state"]==nil
                  next
                else
                  story_state_trans.current_state=change["original_values"]["current_state"]
                end
              end

              if change["new_values"] == nil
                next
              else
                story_state_trans.new_state=change["new_values"]["current_state"]
              end

              if change["new_values"]["updated_at"]==nil
                next
              else
                story_state_trans.commit_time=change["new_values"]["updated_at"]
              end

              story_state_trans.save!
          end
        end

    # ========github stuff 
        if activity["kind"]=="comment_create_activity"
             # puts activity["kind"]
              activity["changes"].each do |change|
                # puts "new values",change["new_values"]
                if change["new_values"]["text"]==nil
                  next
                else
                  # puts "comment_url:",change["new_values"]["text"]
                  comment_url = change["new_values"]["text"].to_s
                  x_url = URI.extract(comment_url, /http(s)?/)
                  puts "x_url:",x_url
                  array=x_url.to_s.split('/')
                  owner=array[3]
                  repos=array[4]
                  shaPlus=array[6]
                  if(shaPlus==nil)
                    puts "shaPlus is nil"
                    next
                  end
                  sha=shaPlus[0..-3]
                  # puts owner
                  # puts repos
                  # puts sha     
                  github_uri = "https://api.github.com/repos/"+owner+"/"+repos+"/commits/"+sha+"?access_token="+github_token
                  if story_updateX==nil or story_updateX.cm_update_before==nil
                  else
                    github_uri+= "&since="+story_updateX.cm_update_before
                    # params = { :since =>story_updateX.cm_update_before} 
                  end
                  puts "github_url:",github_uri
                  c = Curl::Easy.new(github_uri) do |curl| 
                      curl.headers["User-Agent"]=owner
                      curl.verbose = true
                  end
                  c.perform
                  res_status=c.header_str.split(' ')[1]
                  puts "header.status:",res_status
                  # puts "body:",c.body_str
                  if res_status!="200"
                    puts "Response status not ok , can't get data from github by: ",x_url
                    next
                  else
                    hash =JSON.parse c.body_str
                    commit_timeX=hash["commit"]["committer"]["date"]
                    # puts "!!!!date:",commit_timeX
                    if cm_update_before<commit_timeX
                      cm_update_before=commit_timeX
                    end
                    # puts "stats:",hash["stats"]
                    stats=GithubStat.new
                    stats.story_id=pe.story_id
                    stats.committer_github=hash["commit"]["committer"]["name"]
                    stats.commit_time=hash["commit"]["committer"]["date"]
                    stats.total=hash["stats"]["total"]
                    stats.addition=hash["stats"]["additions"]
                    stats.deletion=hash["stats"]["deletions"]
                    stats.message=hash["commit"]["message"]
                    stats.committer_ptracker , stats.status =parse_message(stats.message)
                    stats.file=hash["files"].to_s
                    stats.save!
                  end
                end
              end
        end
      end

      puts "ac_update_before,",ac_update_before
      if story_updateX==nil
          story_update=StoryUpdate.new
          story_update.story_id=pe.story_id
          story_update.ac_update_before=ac_update_before
          story_update.cm_update_before=cm_update_before
          story_update.save!
      else
          story_updateX.update(ac_update_before:ac_update_before)
          story_updateX.update(cm_update_before:cm_update_before)
      end
        
  

    end

    render plain: "Signup failed."

  end




  def index
    puts "=====",__method__,"====="
    # cookies[:token]="0e8a2bbff4a6c292f81d14dfde98a2c8" #kami's token
     # cookies[:token]="907a8e2a34bdd3299613a1ae64776498" #jeremy's token
    # ea13e2d0dbd091e8264cf1bea76b5967157aa4ee  #jeremy's github token
    ptracker_token=session[:ptracker_token]
    date=params[:date]
    if date==nil
      dateHyphen=Date.today.to_formatted_s(:db).to_s
    else
      dateHyphen=GetFormattedDateHyphen(date)
      @dateSlash=GetFormattedDateSlash(date)
    end
    puts "params[:date]:",params[:date]
    puts "date:",dateHyphen
    token =session[:ptracker_token].to_s
    @odtype = params[:ordertype].to_s
    @odtype +=",project_name,story_name asc"
    # puts "ordertype", @odtype
    # @p_entries = PEntry.where("token = ? AND date = ?",token,dateHyphen).order(@odtype)
    # sql = "Select * from p_entries as t1 left outer join dones as t2 on t2.story_id =t1.story_id and t2.done_date=t1.date where t1.date='"+dateHyphen+"' and t1.token='"+ptracker_token+"'"
    @p_entries= PEntry.includes(:done).joins("left outer join dones on dones.story_id =p_entries.story_id and dones.done_date=p_entries.date")
                      .where('p_entries.token=? AND p_entries.date=?', ptracker_token ,  dateHyphen)
    # @p_entries= ActiveRecord::Base.connection.execute(sql)
    respond_to do |format|
      format.html
      format.js    
      format.json  do
        render(json:@p_entries)
      end
    end
  end


     

  # GET /p_entries/1
  # GET /p_entries/1.json
  def show  
  end



  # GET /p_entries/new
  def new
    @p_entry = PEntry.new
  end

  # GET /p_entries/1/edit
  def edit
  end

  # POST /p_entries
  # POST /p_entries.json
  def create
    puts "create start"
    @p_entry = PEntry.new(p_entry_params)

    token=session[:ptracker_token].to_s
    puts "token:",token
    client = TrackerApi::Client.new(token: token) 

    str=params[:p_entry][:ptracker].to_s
    story=client.story(str)
    project = client.project(story.project_id)
    
   # project  = client.project(1121980)         # Find project with given ID
    @p_entry.token=token
    @p_entry.projectid=story.project_id
    @p_entry.project=project.name
    @p_entry.story=story.name
    @p_entry.storytype=story.story_type
    @p_entry.storydescription=story.description
    @p_entry.date=Date.today.to_formatted_s(:db).to_s

   # params[:task][:assignmentId]
    respond_to do |format|
      if @p_entry.save
        format.html { redirect_to @p_entry, notice: 'P entry was successfully created.' }
        format.json { render :show, status: :created, location: @p_entry }
        


      else
        format.html { render :new }
        format.json { render json: @p_entry.errors, status: :unprocessable_entity }
      end
    end
  end

  # PATCH/PUT /p_entries/1
  # PATCH/PUT /p_entries/1.json
  def update
    puts "update start"
    respond_to do |format|
      if @p_entry.update(p_entry_params)
        format.html { redirect_to @p_entry, notice: 'P entry was successfully updated.' }
        format.json { render :show, status: :ok, location: @p_entry }
      else
        format.html { render :edit }
        format.json { render json: @p_entry.errors, status: :unprocessable_entity }
      end
    end
  end

  # DELETE /p_entries/1
  # DELETE /p_entries/1.json
  def destroy
    puts "destroy start"
    @p_entry.destroy
    respond_to do |format|
      format.html { redirect_to @p_entry, notice: 'P entry was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

  private
    # Use callbacks to share common setup or constraints between actions.
    def set_p_entry
      @p_entry = PEntry.find(params[:id])
    end

    # Never trust parameters from the scary internet, only allow the white list through.
    def p_entry_params
      params.require(:p_entry).permit(:project_name, :story_type, :story_id, :status)
    end

    #helper function


end
